package ru.aslanov.schedule.server.services;

import ru.aslanov.schedule.model.*;
import ru.aslanov.schedule.server.AbstractService;
import ru.aslanov.schedule.server.AccessDeniedException;
import ru.aslanov.schedule.server.AccessManager;
import ru.aslanov.schedule.server.InputLangUtil;
import ru.aslanov.schedule.utils.XMLUtil;

import javax.jdo.JDOObjectNotFoundException;
import javax.jdo.PersistenceManager;
import javax.jdo.annotations.PersistenceAware;
import javax.servlet.http.HttpServletRequest;
import javax.xml.datatype.DatatypeConstants;
import java.util.Collection;
import java.util.Collections;

/**
 * Created by IntelliJ IDEA.
 * Created: Feb 3, 2010 3:43:54 PM
 *
 * @author Sergey Aslanov
 */
@PersistenceAware
public class ScheduleService extends AbstractService<Schedule> {
    @Override
    protected Object doFetch(HttpServletRequest request) throws Exception {
        PersistenceManager pm = getPersistanceManager();
        //try {
            final String key = request.getParameter("encodedKey");
            Collection res;
            if (key != null) {
                if (AccessManager.getInstance().hasAccessToSchedule(key, Operation.VIEW)) {
                    try {
                        res = Collections.singletonList(pm.getObjectById(Schedule.class, key));
                    } catch (JDOObjectNotFoundException e) {
                        res = Collections.EMPTY_LIST;
                    }
                } else {
                    res = Collections.EMPTY_LIST; 
                }
            } else {
                res = AccessManager.getInstance().getUserSchedules(pm);
            }


            return convertToDataList(res, request, pm);
        //} finally {
            //pm.close();
        //}
    }

    @Override
    protected String getDefaultInputLang(HttpServletRequest request) {
        final String key = request.getParameter("encodedKey");
        if (key != null) {
            final Schedule schedule = getPersistanceManager().getObjectById(Schedule.class, key);
            return schedule.getDefaultInputLanguage();
        } else
            return null;
    }

    @Override
    protected void fillDataItem(DataItem dataItem, Schedule object, HttpServletRequest request, PersistenceManager pm) throws Exception {
        if (request.getParameter("encodedKey") == null) {
            InputLangUtil.setThreadLocalInputLang(object.getDefaultInputLanguage(), object.getDefaultInputLanguage());
        }
        super.fillDataItem(dataItem, object, request, pm);
        setAttr(dataItem, "name", object.getName());
        final Document document = object.getPublishedDocument();
        setAttr(dataItem, "publishedUrl", document != null ? ("/public/document?scheduleKey=" + object.getEncodedKey()) : null);
        setAttr(dataItem, "publishDate", document != null ? XMLUtil.date2XmlDate(document.getCreated(), DatatypeConstants.DATETIME) : null);
        setAttr(dataItem, "city", object.getCity());
        setAttr(dataItem, "publishUrl", object.getPublishUrl());

        final AccessManager.ScheduleUserInfo scheduleUserInfo = AccessManager.getInstance().getScheduleUserInfo(object.getEncodedKey());
        setAttr(dataItem, "isScheduleAdmin", scheduleUserInfo.isScheduleAdmin());
        setAttr(dataItem, "teacherKey", scheduleUserInfo.getTeacherKey());
        setAttr(dataItem, "defaultInputLanguage", object.getDefaultInputLanguage());

        final GoogleCalendarSync googleCalendarSync = object.getGoogleCalendarSync();
        setAttr(dataItem, "hasSessionToken", googleCalendarSync != null && googleCalendarSync.getSessionToken() != null);
        setAttr(dataItem, "lastGCalPublishDate", googleCalendarSync != null ? googleCalendarSync.getLastPublishDate() : null);

    }

    @Override
    protected void makeObjectPersistent(PersistenceManager pm, Schedule object, HttpServletRequest request) {
        final AccessManager accessManager = AccessManager.getInstance();
        object.setCreatedBy(accessManager.getEmail());
        pm.makePersistent(object);
        if (!accessManager.isAdmin()) {
            final User user = new User();
            user.setEmail(accessManager.getEmail());
            user.setIsAdmin(true);
            object.getUsers().add(user);
        }
    }

    @Override
    protected Class<Schedule> getEntityClass() {
        return Schedule.class;
    }

    @Override
    protected boolean checkPermission(Schedule existingEntity, HttpServletRequest request, PersistenceManager pm, Operation operation) throws AccessDeniedException {
        final AccessManager am = AccessManager.getInstance();
        if (existingEntity != null) {
            return am.isScheduleAdmin(existingEntity.getEncodedKey());
        } else {
            // allow create for everyone
            return true;
            //return am.isAdmin();
        }
    }
}
